//////////////////////////////////////////ok
#include"stdafx.h"
#include "bochs.h"



void IA32_CPU::MUL_ALEb(Ia32_Instruction_c *i)
{
  Bit8u op2, op1;

  op1 = AL;

  if (i->modC0()) 
  {
    op2 = IA32_READ_8BIT_REGx(i->rm(),i->extend8bitL());
  }
  else 
  {
    read_virtual_byte(i->seg(), IA32_RMAddr(i), &op2);
  }

  Bit32u product_16  = ((Bit16u) op1) * ((Bit16u) op2);
  Bit8u product_8l = (product_16 & 0xFF);
  Bit8u product_8h =  product_16 >> 8;
  IA32_SET_FLAGS_OSZAPC_S1S2_8(product_8l, product_8h, IA32_INSTR_MUL8);
  AX = product_16;

}

void IA32_CPU::IMUL_ALEb(Ia32_Instruction_c *i)
{
  Bit8s op2, op1;

  op1 = AL;

  if (i->modC0()) 
  {
    op2 = IA32_READ_8BIT_REGx(i->rm(),i->extend8bitL());
  }
  else 
  {
    read_virtual_byte(i->seg(), IA32_RMAddr(i), (Bit8u *) &op2);
  }

  Bit16s product_16 = op1 * op2;
  Bit8u product_8l = (product_16 & 0xFF);
  Bit8u product_8h =  product_16 >> 8;
  IA32_SET_FLAGS_OSZAPC_S1S2_8(product_8l, product_8h, IA32_INSTR_IMUL8);
  AX = product_16;
}

void IA32_CPU::DIV_ALEb(Ia32_Instruction_c *i)
{
  Bit8u op2, quotient_8l, remainder_8;
  Bit16u quotient_16, op1;

  op1 = AX;
  if (i->modC0()) 
  {
    op2 = IA32_READ_8BIT_REGx(i->rm(),i->extend8bitL());
  }
  else 
  {
    read_virtual_byte(i->seg(), IA32_RMAddr(i), &op2);
  }

  if (op2 == 0) 
  {
    exception(IA32_BX_DE_EXCEPTION, 0, 0);
  }

  quotient_16 = op1 / op2;
  remainder_8 = op1 % op2;
  quotient_8l = quotient_16 & 0xFF;
  if (quotient_16 != quotient_8l)
  {
    exception(IA32_BX_DE_EXCEPTION, 0, 0);
  }

  AL = quotient_8l;
  AH = remainder_8;

}

void IA32_CPU::IDIV_ALEb(Ia32_Instruction_c *i)
{
  Bit8s op2, quotient_8l, remainder_8;
  Bit16s quotient_16, op1;

  op1 = AX;
  if (i->modC0()) 
  {
    op2 = IA32_READ_8BIT_REGx(i->rm(),i->extend8bitL());
  }
  else 
  {
    read_virtual_byte(i->seg(), IA32_RMAddr(i), (Bit8u *) &op2);
  }

  if (op2 == 0)
    exception(IA32_BX_DE_EXCEPTION, 0, 0);

  if ((op1 == ((Bit16s)0x8000)) && (op2 == -1))
    exception(IA32_BX_DE_EXCEPTION, 0, 0);

  quotient_16 = op1 / op2;
  remainder_8 = op1 % op2;
  quotient_8l = quotient_16 & 0xFF;

  if (quotient_16 != quotient_8l)
    exception(IA32_BX_DE_EXCEPTION, 0, 0);

  AL = quotient_8l;
  AH = remainder_8;

}
